// =============================================
// Shader 名称：Fractal/Fractal Surface GPU
// 类型：基于 Unity 的 Surface Shader（表面着色器）
// 用途：用于高效渲染大量分形几何体（比如通过 GPU Instancing 批量绘制的方块、粒子、树干等），
//       每个实例拥有独立的变换（位置、旋转、缩放）和颜色（通过 GetFractalColor 动态计算）。
//       支持标准 PBR 光照、阴影、GPU Instancing。
// =============================================

Shader "Fractal/Fractal Surface GPU" {

    SubShader {

        CGPROGRAM

        // 声明这是一个 Surface Shader，并使用内置的 Standard（PBR）光照模型
        // fullforwardshadows：支持完整的前向渲染阴影
        // addshadow：为该物体生成额外的阴影投射 Pass（使其能投射阴影到其他物体上）
        #pragma surface ConfigureSurface Standard fullforwardshadows addshadow

        // 启用 GPU Instancing 支持，并指定：
        // - assumeuniformscaling：假设所有实例的缩放是统一的（可优化性能）
        // - procedural:ConfigureProcedural：告诉 Unity 使用名为 ConfigureProcedural 的函数来设置每实例的变换（来自 _Matrices 缓冲区）
        #pragma instancing_options assumeuniformscaling procedural:ConfigureProcedural

        // 允许在编辑器中修改 Shader 代码后自动重新编译（开发阶段方便调试，但可能影响编辑器性能）
        #pragma editor_sync_compilation

        // 指定该 Shader 的最低支持的 Shader Model 版本（4.5 支持 ComputeBuffer、GPU Instancing 等高级特性）
        #pragma target 4.5

        // 引入自定义的 HLSL 文件，其中包含：
        // - ConfigureProcedural()：设置每个实例的世界变换矩阵
        // - GetFractalColor()：基于 InstanceID 计算每个实例的颜色
        // - 其它 Instancing 相关变量和函数（如 _Matrices, _SequenceNumbers）
        #include "FractalGPU.hlsl"

        // -------------------------------
        // 【Input 结构体】：定义从顶点着色器传递给表面函数的输入数据
        // -------------------------------
        struct Input {
            // 世界空间中的位置，可用于后续根据位置调整颜色、法线等（虽然这里没用到）
            float3 worldPos;
        };

        // -------------------------------
        // 【材质属性】：从 Material 中暴露的参数（但此例中仅使用了 _Smoothness）
        // -------------------------------
        float _Smoothness; // 表面光滑度，用于控制 PBR 材质的高光模糊程度

        // -------------------------------
        // 【表面着色函数】：定义该物体的表面外观（颜色、光滑度、法线等）
        // -------------------------------
        void ConfigureSurface (Input input, inout SurfaceOutputStandard surface) {
            // 设置物体的基础颜色（Albedo）为：通过 GetFractalColor() 动态计算出的颜色中的 RGB 部分
            // 每个实例根据其 ID 将显示不同颜色（程序化颜色分配）
            surface.Albedo = GetFractalColor().rgb;

            // 设置物体的光滑度（Smoothness）为：从 GetFractalColor() 返回的 Alpha 通道值
            // 注意：这里代码写了两遍 `surface.Smoothness =`，第二个是多余的，保留一个即可
            surface.Smoothness = GetFractalColor().a; // Alpha 通道用于控制光泽 / 高光模糊度
        }
        ENDCG
    }

    FallBack "Diffuse"
}